from django.shortcuts import render
from rest_framework.generics import ListAPIView
from rest_framework.views import APIView
from rest_framework.response import Response
from functools import reduce
from rest_framework.pagination import PageNumberPagination
from rest_framework_jwt.utils import jwt_decode_handler
import redis
# Create your views here.
from goods.serializer import CarouselSer, GoodsSer, CateSer, GoodsImgSer, GoodsCollectSer
from goods.models import *
from haystack.views import SearchView
from django.http import JsonResponse


# 轮播图
class CarouselView(ListAPIView):
    queryset = Carousel.objects.all()
    serializer_class = CarouselSer


# 根据类别名获取商品数据
class GoodsCateName(APIView):
    def post(self, request):
        name = request.data.get("categoryName")
        cate = Category.objects.get(cate_name=name)
        # 反向查询
        goods = cate.goods_set.all()
        # 序列化对象
        goods_ser = GoodsSer(goods, many=True)
        # 返回响应
        return Response(goods_ser.data)


# 热门商品
class HotGoods(APIView):
    def post(self, request):
        # 获取前端传来的类被信息
        cate_name = request.data.get("categoryName")
        # 列表推导式存放在商品类别里
        cates = [Category.objects.get(cate_name=name) for name in cate_name]
        # 根据商品类别存放商品
        goods = [cate.goods_set.all() for cate in cates]
        # 根据商品的销量进行排序
        res = reduce(lambda x, y: x | y, goods).order_by('-count')
        ser = GoodsSer(res, many=True)
        return Response(ser.data)


# 获取类别
class CategoryView(APIView):
    def post(self, request):
        cates = Category.objects.all()
        ser = CateSer(cates, many=True)
        return Response(ser.data)


# 根据id获取类别的所有商品
class GoodsCateId(APIView):
    def get(self, request):
        cate_id = request.query_params['categoryID']
        try:
            cate = Category.objects.get(id=cate_id)
        except Exception as e:
            print(e)
            return Response({'msg': '没有此类别'})
        # 根据类别获取所有的商品
        goods = cate.goods_set.all()
        goods_ser = GoodsSer(goods, many=True)
        return Response(goods_ser.data)


# 分页器
class Pagination(PageNumberPagination):
    page_size_query_param = 'pageSize'
    page_query_param = 'page'
    page_size = 7


# 获取所有商品
class GoodsView(ListAPIView):
    queryset = Goods.objects.all()
    serializer_class = GoodsSer
    pagination_class = Pagination


# 商品图片
class GoodPicture(APIView):
    def get(self, request):
        # 获取前端传递的商品id
        goods_id = request.query_params.get("productID")
        if goods_id:
            try:
                goods = Goods.objects.get(id=goods_id)
            except Exception as e:
                print(e)
                return Response({'msg': '此商品不存在', 'code': 400})
            # 序列化对象
            imgs = goods.goodimg_set.all()
            ser = GoodsImgSer(imgs, many=True)
            return Response(ser.data)
        else:
            # id获取失败
            return Response({'msg': '商品id 获取失败', 'code': 400})


# 商品详情
class GoodDetail(APIView):
    def get(self, request):
        # 获取前端传递的商品id
        goods_id = request.query_params.get("productID")
        if goods_id:
            try:
                goods = Goods.objects.get(id=goods_id)
            except Exception as e:
                print(e)
                return Response({'msg': '此商品不存在', 'code': 400})
            # 序列化对象
            ser = GoodsSer(goods)
            return Response(ser.data)
        else:
            # id获取失败
            return Response({'msg': '商品id 获取失败', 'code': 400})


# 添加浏览记录
class AddHistory(APIView):
    def post(self, request):
        # 获取前端传递的数据
        good_id = request.data.get("productID")
        token = request.data.get("token")
        # print('token=====》》》', token)
        # 无token时
        if not token:
            return Response({'msg': '请先登录', 'code': 400})
        else:
            # 解码
            payload = jwt_decode_handler(token)
            # print('payload>>', payload)
            # 查询用户
            uid = payload.get("user_id")
            # 构造历史记录的key
            histry_key = "history_%s" % uid
            # 链接redis
            redis_cli = redis.Redis(host='127.0.0.1', port=6379)
            # 添加历史记录
            # 先删除存在的次商品
            redis_cli.lrem(histry_key, 0, good_id)
            # 添加
            redis_cli.lpush(histry_key, good_id)
            # 保留5条数据
            redis_cli.ltrim(histry_key, 0, 4)
            # 关闭连接
            redis_cli.close()

            return Response({'msg': '添加历史记录成功', 'code': 200})


# 商品收藏
class CollectView(APIView):
    def post(self, request):
        # 获取前端传递的数据
        good_id = request.data.get("product_id")
        user = request.data.get("user")
        # 判断id对应的商品是否存在
        if not good_id:
            return Response({'msg': '商品错误', 'code': 400})
        try:
            user = Users.objects.get(username=user['userName'])
        except Exception as e:
            print(e)
            return Response({'msg': '没有此用户', 'code': 400})
        # 存入商品收藏表
        try:
            good = Goods.objects.get(id=good_id)
        except Exception as e:
            print(e)
            return Response({'msg': '收藏失败', 'code': 400})
        goods = GoodsCollect.objects.create(user=user, goods=good)
        ser = GoodsCollectSer(goods)
        return Response({'msg': '收藏成功', 'code': 200, 'data': ser.data})


# 查看收藏
class GoodsFav(APIView):
    def post(self, request):
        # 获取前端传递的数据
        dict_user = request.data.get("user")
        token = request.data.get("token")
        # 判断获取的数据是否为空，是空就让用户先登录
        if not all([dict_user, token]):
            return Response({'msg': '请先登录', 'code': 400})
        # 判断传来的用户信息是否一致
        try:
            user = Users.objects.get(username=dict_user['userName'])
        except Exception as e:
            print(e)
            return Response({'msg': '没有此用户', 'code': 400})
        # 校验token
        payload = jwt_decode_handler(token)
        user_id = payload.get('user_id')
        # 校验传来的用户和token中的是否一致
        if user_id == user.id:
            products = user.goodscollect_set.all()
            collect_goods = []
            for i in products:
                collect_goods.append({
                    "id": i.goods.id,
                    'sku_name': i.goods.sku_name,
                    "price": i.goods.price,
                    "selling_price": i.goods.selling_price,
                    "img": i.goods.img,
                    "title": i.goods.title,
                    "instruction": i.goods.instruction
                })
            return Response({'msg': 'ok', 'data': collect_goods, 'code': 200})
        else:
            return Response({'msg': '用户信息错误', 'code': 400})


# 删除收藏
class CollectDel(APIView):
    def delete(self, request):
        # 获取前端传递来的数据
        dict_user = request.data.get("user")
        pid = request.data.get("product_id")
        try:
            user = Users.objects.get(username=dict_user['userName'])
        except Exception as e:
            print(e)
            return Response({'msg': '没有此用户', 'code': 400})
        GoodsCollect.objects.filter(user=user, goods_id=pid).delete()
        return Response({"msg": '删除成功', 'code': 200})


class MySearchView(SearchView):
    """自定义返回json"""
    def create_response(self):
        # 重载create_response来实现接口编写
        # 返回上下文的数据
        # {' query': '电视', 'form': <ModelSearchForm bound=True, valid=True, fields=(q;models)>,
        # 'page': <Page 1 of 1>, 'paginator': <django.core.paginator.Paginator object at 0x7f7d69a0d0>,
        # 'suggestion': None
        # }
        context = super().get_context()
        print(">>>context", context)
        # 获取当前的分页
        current_page = context.get("page")
        # 查询结果的分页
        paginator = context.get("paginator")
        goods_list = []
        print("商品列表》》》", current_page.object_list)
        for i in current_page.object_list:
            # 将每一个商品对象放入列表
            goods_list.append(i.object)
        # 对商品列表序列化
        goods_ser = GoodsSer(goods_list, many=True)
        print("goods_list>>>>", goods_list)

        # 这里的序列化模型类是之前章节定义好的

        # 返回响应
        return JsonResponse({
            "code": 200,
            "msg": "查询商品成功！",
            "product": goods_ser.data,
            "total": len(goods_list)
        })